package com.example.demo.Controller.Ip_Table;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.demo.ServiceImpl.Ip_Table.IpTableServiceImpl;
import com.example.demo.Entity.Ip_Table.IpTable;
import com.example.demo.Utils.Result.R;
import io.micrometer.common.util.StringUtils;
import io.netty.util.internal.StringUtil;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import org.jetbrains.annotations.NotNull;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.concurrent.TimeUnit;

@RestController
@CrossOrigin(origins = "*")
@RequestMapping("/ipTable")
@Tag(name = "IpTableController", description = "IpTableController 相关接口")
public class IpTableController {

    @Resource
    private IpTableServiceImpl ipTableService;

    @Resource
    private RedisTemplate<String, Object> redisTemplate;

    @PostMapping
    @Operation(summary = "保存或更新 IpTable 信息", description = "根据传入的 IpTable 对象保存或更新信息")
    @ApiResponses(value = {
            @ApiResponse(responseCode = "200", description = "保存或更新成功", content = @Content(schema = @Schema(implementation = Boolean.class)))
    })
    public Boolean save(@RequestBody IpTable ipTable) {
// 保存或更新数据后，删除相关缓存
        redisTemplate.delete("ipTable:all");
        return ipTableService.saveOrUpdate(ipTable);
    }

    @DeleteMapping("/{id}")
    @Operation(summary = "根据 ID 删除 IpTable 信息", description = "根据传入的 ID 删除对应的 IpTable 信息")
    @ApiResponses(value = {
            @ApiResponse(responseCode = "200", description = "删除成功", content = @Content(schema = @Schema(implementation = Boolean.class)))
    })
    public Boolean delete(@PathVariable(value = "id") Integer id) {
// 删除数据后，删除相关缓存
        redisTemplate.delete("ipTable:all");
        redisTemplate.delete("ipTable:id:" + id);
        return ipTableService.removeById(id);
    }

    @GetMapping
    @Operation(summary = "获取所有 IpTable 信息", description = "获取所有 IpTable 的列表信息")
    @ApiResponses(value = {
            @ApiResponse(responseCode = "200", description = "获取成功", content = @Content(schema = @Schema(implementation = R.class)))
    })
    public R findAll() {
        String key = "ipTable:all";
        @SuppressWarnings("unchecked")
        List<IpTable> ipTableList = (List<IpTable>) redisTemplate.opsForValue().get(key);
        if (ipTableList == null) {
            ipTableList = ipTableService.list();
            redisTemplate.opsForValue().set(key, ipTableList, 60, TimeUnit.MINUTES);
        }
        return R.ok().put("ipTableList", ipTableList);
    }

    @GetMapping("/{id}")
    @Operation(summary = "根据 ID 获取 IpTable 信息", description = "根据传入的 ID 获取对应的 IpTable 信息")
    @ApiResponses(value = {
            @ApiResponse(responseCode = "200", description = "获取成功", content = @Content(schema = @Schema(implementation = R.class)))
    })
    public R findOne(@PathVariable(value = "id") Integer id) {
        String key = "ipTable:id:" + id;
        IpTable ipTable = (IpTable) redisTemplate.opsForValue().get(key);
        if (ipTable == null) {
            ipTable = ipTableService.getById(id);
            if (ipTable != null) {
                redisTemplate.opsForValue().set(key, ipTable, 60, TimeUnit.MINUTES);
            }
        }
        return R.ok().put("ipTable", ipTable);
    }

    @GetMapping("/page")
    @Operation(summary = "分页获取 IpTable 信息", description = "根据传入的页码和每页数量分页获取 IpTable 信息")
    @ApiResponses(value = {
            @ApiResponse(responseCode = "200", description = "获取成功", content = @Content(schema = @Schema(implementation = R.class)))
    })
    @Parameter(name = "pageNum", in = ParameterIn.QUERY, description = "页码", required = true)
    @Parameter(name = "pageSize", in = ParameterIn.QUERY, description = "每页数量", required = true)
    public R findPage(@RequestParam(value = "pageNum") Integer pageNum,
                      @RequestParam(value = "pageSize") Integer pageSize,@RequestParam(value = "keyword",required = false) String keyword) {
        LambdaQueryWrapper<IpTable> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.orderByDesc(IpTable::getIpId);
        if(keyword!=null){
            queryWrapper.like(IpTable::getIpAddress,keyword).or().like(IpTable::getResourceName,keyword);
        }
        Page<IpTable> ipTablePage = ipTableService.page(new Page<>(pageNum, pageSize), queryWrapper);
        return R.ok().put("ipTablePage", ipTablePage);
    }

    @Transactional(rollbackFor = Exception.class)
    @PostMapping("/block")
    @Operation(summary = "封禁IP", description = "根据传入的IP封禁")
    @ApiResponses(value = {
            @ApiResponse(responseCode = "200", description = "封禁成功", content = @Content(schema = @Schema(implementation = Boolean.class)))
    })
    public Boolean block(@RequestParam String ipAddress) {
        return changeIsBlock(ipAddress,1);
    }

    private @NotNull Boolean changeIsBlock(String ipAddress,Integer isBlock) {
        LambdaQueryWrapper<IpTable> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(IpTable::getIpAddress, ipAddress);
        List<IpTable> ipTableList = ipTableService.list(queryWrapper);
        if(ipTableList==null||ipTableList.isEmpty()){
            return Boolean.FALSE;
        }
        ipTableList.forEach(ipTable -> {
            ipTable.setIsBlack(isBlock);
        });
        return ipTableService.updateBatchById(ipTableList);
    }

    @PostMapping("/unblock")
    @Operation(summary = "解封IP", description = "根据传入的IP解封")
    @ApiResponses(value = {
            @ApiResponse(responseCode = "200", description = "解封成功", content = @Content(schema = @Schema(implementation = Boolean.class)))
    })
    public Boolean unblock(@RequestParam String ipAddress) {
       return changeIsBlock(ipAddress,0);
    }
}